%%%---------------------------------------------------------------------------------------
%%% @author    Stuart Jackson <sjackson@simpleenigma.com> [http://erlsoft.org]
%%% @copyright 2006 - 2008 Simple Enigma, Inc. All Rights Reserved.
%%% @doc       Elestic Cloud Computing Libraray for version 2008-02-01
%%% @reference See <a href="http://erlsoft.org/modules/eifaws" target="_top">Erlang Software Framework</a> for more information
%%% @reference See <a href="http://eifaws.googlecode.com" target="_top">ErlMail Google Code Repository</a> for more information
%%% @version   0.0.1
%%% @since     0.0.1
%%% @end
%%%
%%%
%%% The MIT License
%%%
%%% Copyright (c) 2008 Stuart Jackson, Simple Enigma, Inc. All Righs Reserved
%%%
%%% Permission is hereby granted, free of charge, to any person obtaining a copy
%%% of this software and associated documentation files (the "Software"), to deal
%%% in the Software without restriction, including without limitation the rights
%%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
%%% copies of the Software, and to permit persons to whom the Software is
%%% furnished to do so, subject to the following conditions:
%%%
%%% The above copyright notice and this permission notice shall be included in
%%% all copies or substantial portions of the Software.
%%%
%%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
%%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
%%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
%%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
%%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
%%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
%%% THE SOFTWARE.
%%%
%%%
%%%---------------------------------------------------------------------------------------

-module(eifaws_ec2_2006_10_01).
-author('sjackson@simpleenigma.com').
-include("../include/eifaws.hrl").
-include_lib("xmerl/include/xmerl.hrl").

-export([ec2/2]).



ec2('AuthorizeSecurityGroupIngress',Message) ->
	XMLRoot = eifaws_util:to_xml(Message),
	eifaws_util:aws_atom(XMLRoot);
ec2('CreateKeyPair',Message) ->
	XMLRoot = eifaws_util:to_xml(Message),
	KeyName = eifaws_util:aws_string(XMLRoot,"keyName"),
	KeyFingerprint =  eifaws_util:aws_string(XMLRoot,"keyFingerprint"),
	KeyMaterial =  eifaws_util:aws_string(XMLRoot,"keyMaterial"),
	#key_pair{key_name = KeyName, key_fingerprint = KeyFingerprint, key_material = KeyMaterial};
ec2('CreateSecurityGroup',Message) ->
	XMLRoot = eifaws_util:to_xml(Message),
	eifaws_util:aws_atom(XMLRoot);
ec2('DeleteKeyPair',Message) ->
	XMLRoot = eifaws_util:to_xml(Message),
	eifaws_util:aws_atom(XMLRoot);
ec2('DeleteSecurityGroup',Message) ->
	XMLRoot = eifaws_util:to_xml(Message),
	eifaws_util:aws_atom(XMLRoot);
ec2('DeregisterImage',Message) ->
	XMLRoot = eifaws_util:to_xml(Message),
	eifaws_util:aws_atom(XMLRoot);
ec2('DescribeImageAttributes',Message) ->
	XMLRoot = eifaws_util:to_xml(Message),
	XMLRoot;


% look into filtering on the parent instead of cleaing out the blank ami_info
ec2('DescribeImages',Message) ->
	XMLRoot = eifaws_util:to_xml(Message),
	Items = eifaws_util:xml_list(XMLRoot,"imagesSet/item"),
	Images = lists:foldl(fun(E,Acc) -> 
		[ImageId,ImageLocation,ImageState,ImageOwnerId,Public,Arch,ImageType] = 
			eifaws_util:xml_extract(E,[{string,"imageId"},{string,"imageLocation"},{atom,"imageState"},{string,"imageOwnerId"},{atom,"isPublic"},{atom,"architecture"},{atom,"imageType"}]),
		ProductCodes = case xmerl_xpath:string("productCodes/item",E) of
			[]     -> [];
			[Item] -> eifaws_util:aws_string(Item,"productCode")
		end,
		AMIInfo = #ami_info{image_id = ImageId, image_location = ImageLocation,image_state = ImageState, image_owner_id = ImageOwnerId, public = Public, arch = Arch, image_type=ImageType, product_codes = ProductCodes},
		[AMIInfo|Acc]
	end,[],Items),
	lists:reverse(Images);

ec2('DescribeInstances',Message) ->
	XMLRoot = eifaws_util:to_xml(Message),
	reservation_set(XMLRoot);

ec2('DescribeKeyPairs',Message) ->
	XMLRoot = eifaws_util:to_xml(Message),
	key_set(XMLRoot);
ec2('DescribeSecurityGroups',Message) ->
	XMLRoot = eifaws_util:to_xml(Message),
	security_group_info(XMLRoot);
ec2('ModifyImageAttribute',Message) ->
	XMLRoot = eifaws_util:to_xml(Message),
	eifaws_util:aws_atom(XMLRoot);
ec2('RegisterImage',Message) ->
	XMLRoot = eifaws_util:to_xml(Message),
	eifaws_util:aws_string(XMLRoot,"imageId");
ec2('ResetImageAttribute',Message) ->
	XMLRoot = eifaws_util:to_xml(Message),
	eifaws_util:aws_atom(XMLRoot);
ec2('RevokeSecurityGroupIngress',Message) ->
	XMLRoot = eifaws_util:to_xml(Message),
	eifaws_util:aws_atom(XMLRoot);
ec2('RunInstances',Message) ->
	XMLRoot = eifaws_util:to_xml(Message),
	[ReservationId,OwnerId] = eifaws_util:xml_extract(XMLRoot,[{string,"reservationId"},{string,"ownerId"}]),
	GroupSet = group_set(XMLRoot),
	InstancesSet = instances_set(XMLRoot),
	#reservation_info{reservation_id = ReservationId, owner_id = OwnerId, groups = GroupSet, instances = InstancesSet};

ec2('TerminateInstances',Message) ->
	XMLRoot = eifaws_util:to_xml(Message),
	instances_set(XMLRoot);

ec2(Command,Message) ->
	{error,{unknown_command,Command,Message}}.



security_group_info(XML) ->
	lists:foldr(fun(E,Acc) -> 
			[OwnerId,GroupName,GroupDesc] = eifaws_util:xml_extract(E,[{string,"ownerId"},{string,"groupName"},{string,"groupDescription"}]),
			IpPermissions = ip_permissions(E),
			[#security_group_info{group_name = GroupName, group_desc = GroupDesc, owner_id = OwnerId, ip_permissions = IpPermissions} | Acc]
	end, [] , xmerl_xpath:string("securityGroupInfo/item",XML)).


ip_permissions(XML) ->
	lists:foldr(fun(E,Acc) -> 
		[IpProtocol,FromPort,ToPort] = eifaws_util:xml_extract(E,[{string,"ipProtocol"},{string,"fromPort"},{string,"toPort"}]),
		[#ip_permissions{ip_protocol = IpProtocol, from_port = FromPort, to_port = ToPort}|Acc]
	end, [], xmerl_xpath:string("ipPermissions/item",XML)).



key_set(XML) ->
	lists:foldr(fun(E,Acc) -> 
			[KeyName,KeyFingerprint,KeyMaterial] = eifaws_util:xml_extract(E,[{string,"keyName"},{string,"keyFingerprint"},{string,"keyMaterial"}]),
			[#key_pair{key_name = KeyName, key_fingerprint = KeyFingerprint, key_material=KeyMaterial} | Acc]
	end, [] , xmerl_xpath:string("keySet/item",XML)).

reservation_set(XMLRoot) ->
	lists:foldr(fun(E,Acc) -> 
		[ReservationId,OwnerId] = eifaws_util:xml_extract(E,[{string,"reservationId"},{string,"ownerId"}]),
		GroupSet = group_set(E),
		InstancesSet = instances_set(E),
		[#reservation_info{reservation_id = ReservationId, owner_id = OwnerId, groups = GroupSet, instances = InstancesSet} | Acc]
	end, [] , xmerl_xpath:string("reservationSet/item",XMLRoot)).
	
group_set(XML) ->
	lists:foldr(fun(E,Acc) -> 
		GroupId = eifaws_util:aws_string(E,"groupId"),
		[GroupId | Acc]
	end, [] ,xmerl_xpath:string("groupSet/item",XML)).
	
instances_set(XML) ->
	lists:foldr(fun(E,Acc) -> 
		[InstanceId,ImageId,PrivateDnsName,DnsName,KeyName,InstanceType,KernelId,RamdiskId] = 
			eifaws_util:xml_extract(E,[{string,"instanceId"},{string,"imageId"},{string,"privateDnsName"},{string,"dnsName"},{string,"keyName"},{atom,"instanceType"},{string,"kernelId"},{string,"ramdiskId"}]),
		ProductCodes = product_codes_set(E),
		Placement = placement(E),
		{InstanceStateName,InstanceStateCode} = instance_state(E),
		{PreviousStateName,PreviousStateCode} = previous_state(E),
		{ShutdownStateName,ShutdownStateCode} = shutdown_state(E),
		[#instance_info{instance_id = InstanceId, image_id = ImageId,private_dns_name = PrivateDnsName, 
			dns_name = DnsName, instance_type = InstanceType, ramdisk_id = RamdiskId, kernel_id = KernelId, 
			key_name = KeyName, placement = Placement, product_codes = ProductCodes, 
			instance_state_name = InstanceStateName, instance_state_code = InstanceStateCode,
			previous_state_name = PreviousStateName, previous_state_code = PreviousStateCode,
			shutdown_state_name = ShutdownStateName, shutdown_state_code = ShutdownStateCode} 
		
		| Acc]
	end, [] ,xmerl_xpath:string("instancesSet/item",XML)).

product_codes_set(XML) -> 
	lists:foldr(fun(E,Acc) -> 
		[eifaws_util:aws_string(E,"productCode") | Acc]
	end, [] , xmerl_xpath:string("productCodesSet/item",XML)).

placement(XML) -> 
	eifaws_util:aws_atom(XML,"placement/availabilityZone").


instance_state(XML) -> instance_state(XML,"instanceState").
instance_state(XML,Path) -> 
	Name = eifaws_util:aws_atom(XML,Path ++ "/name"),
	Code = eifaws_util:aws_integer(XML,Path ++ "/code"),
	{Name,Code}.

shutdown_state(XML) -> instance_state(XML,"shutdownState").
previous_state(XML) -> instance_state(XML,"previousState").




















